<?php
abstract class DomArDomainObject {
	
	const STATUS_NULL = 0;
	const STATUS_NEW = 1;
	const STATUS_CLEAN = 2;
	const STATUS_DIRTY = 3;
	const STATUS_DELETED = 4;
	
	private $id = 0;
	
	private $_status = 0;
	
	private $_dirty = array();
	
	final public function __construct( $id = NULL, $loadContents = true ) {
		if( $id == NULL ) {
			$this->setStatus( self::STATUS_NEW );
		} else {
			$this->setId( $id );
			$this->setStatus( self::STATUS_CLEAN );
		}
		
		if( $id > 0 && $loadContents === true ) {
			$this->loadValues();
		}
	}
	
	// ---------------------------------------------
	// VALIDATION
	// ---------------------------------------------
	
	abstract public function _beforeValidate();
	
	public function validate() {
		
	}
	
	abstract public function _afterValidate();
	
	// ---------------------------------------------
	// INSERT / UPDATE
	// ---------------------------------------------
	
	abstract public function _beforeInsert();
	
	abstract public function _beforeUpdate();
	
	public function save() {
		
	}
	
	abstract public function _afterInsert();
	
	abstract public function _afterUpdate();
	
	// ---------------------------------------------
	// LOAD
	// ---------------------------------------------
	
	public static function load( $id ) {
		
	}
	
	public function loadValues() {
		
	}
	
	// ---------------------------------------------
	// DELETE
	// ---------------------------------------------
	
	abstract public function _beforeDelete();
	
	public function delete() {
		if( $this->getStatus() === self::STATUS_DELETED )
			return;
		
		$this->setStatus( self::STATUS_DELETED );
		$this->_beforeDelete();
		
		// do delete
		
		$this->_afterDelete();
	}
	
	abstract public function _afterDelete();
	
	// ---------------------------------------------
	// CREATE TABLE
	// ---------------------------------------------
	
	abstract public function _beforeCreateTable();
	
	abstract public function createTable();
	
	abstract public function _afterCreateTable();
	
	// ---------------------------------------------
	// GET
	// ---------------------------------------------
	
	final public function getId() {
		return $this->id;
	}
	
	final public function getDirty() {
		return $this->_dirty;
	}
	
	final public function getStatus() {
		return $this->_status;
	}
	
	final public static function getMapper() {
		return call_user_func( get_called_class().'::getInstance' );
	}
	
	// ---------------------------------------------
	// SET
	// ---------------------------------------------
	
	final public function setId( $id ) {
		if( $this->id !== 0 )
			throw new RuntimeException('Object already has id!');
			
		$this->id = $id;
		DomArIdentityMap::add( $this );
	}
	
	final public function setDirty( array $dirty ) {
		$this->dirty = $dirty;
	}
	
	final public function setStatus( $status ) {
		if( $status == $this->_status )
			return;
		
		$unitOfWork = DomArSession::getCurrent();
		$unitOfWork->unregister( $this );
		$this->_status = $status;
		$unitOfWork->register( $this );
	}

	/**
	 * Return this object id generator id group name.
	 * @return String
	 */
	abstract public function getIdGroupName();
}
?>